<?php

namespace App\Services\Impl;

use App\Library\ScheduleLibraryInterFace;
use App\Library\ZhjyLibraryInterface;
use App\Services\ZhjyServiceInterface;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Support\Facades\Log;
use App\Models\ScheduleTask;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Schema;
use App\Services\ScheduleServiceInterFace;
use App\Exceptions\BusinessException;

class ScheduleServiceImpl implements ScheduleServiceInterFace
{
    
    protected $scheduleLibrary;

    public function __construct(ScheduleLibraryInterFace $scheduleLibraryInterFace)
    {
        $this->scheduleLibrary = $scheduleLibraryInterFace;
    }
    /**
     * 从数据库注册所有调度任务
     */
    public function registerTasks($schedule): void
    {
        try {
            // 首先检查表是否存在
            if (!Schema::hasTable('schedule_tasks')) {
                Log::warning('schedule_tasks 表不存在，跳过任务调度注册');
            }
            
            // 从数据库中获取所有启用的任务
            $tasks = ScheduleTask::where('is_active', true)->get();
            
            // 如果没有任务，记录日志并返回
            if ($tasks->isEmpty()) {
                Log::info('没有找到启用的调度任务');
                return;
            }
            
            // 遍历所有任务进行注册
            foreach ($tasks as $task) {
                $this->registerTask($schedule, task: $task);
            }
            
            Log::info('已注册 ' . $tasks->count() . ' 个调度任务');
        } catch (QueryException $e) {
            // 数据库查询错误，可能是表不存在
            Log::error('数据库查询错误: ' . $e->getMessage());
        } catch (\Exception $e) {
            Log::error('注册调度任务失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 注册单个任务
     */
    private function registerTask(Schedule $schedule, ScheduleTask $task)
    {
        try {

            $scheduledTask = $schedule->call(function () use ($task) {
                // 如果设置了抖动时间，添加随机延迟
            if (!empty($task->jitter_time)) {
                $startTime = microtime(true);
                Log::info('我正在抖动...........' . $task->jitter_time);
                // 使用 Laravel 12 兼容的 after 方法
                $jitterRange = explode('-', $task->jitter_time);
                $minJitter = (int)$jitterRange[0];
                $maxJitter = (int)$jitterRange[1];
                sleep(rand($minJitter, $maxJitter));
                Log::info('我抖动完了...........');
                $endTime = microtime(true);
                $executionTime = round($endTime - $startTime, 2);
                Log::info("我抖动完了，实际耗时: {$executionTime} 秒");

            }

            // 如果设置了延迟时间，添加固定延迟
            if (!empty($task->delay_time)) {
                $startTime = microtime(true);
                Log::info('我开始固定延时: ' . $task->delay_time);
                
                sleep((int)$task->delay_time);
                
                $endTime = microtime(true);
                $executionTime = round($endTime - $startTime, 2);
                Log::info("固定延时完成，实际耗时: {$executionTime} 秒");
            }
                switch ($task->name) {
                    case 'dawn_job':
                        $this->scheduleLibrary->dailyCheckInTask($task);
                        break;
                    case 'log_job':
                        $this->scheduleLibrary->logTask($task);
                        break;
                    default:
                        # code...
                        break;
                }
            });
            
            // 设置 cron 表达式
            $scheduledTask->cron($task->cron_expression);
            
            // 设置任务名称
            $scheduledTask->name($task->name);
            // 防止任务重复执行，如果上一个任务还在运行，则跳过当前执行
            // $scheduledTask->withoutOverlapping(60); // 设置锁定时长为60分钟

            
            Log::info("已注册任务: {$task->name}, Cron表达式: {$task->cron_expression}");
        } catch (\Exception $e) {
            Log::error("注册任务 {$task->name} 失败: " . $e->getMessage());
        }
    }
    
    /**
     * 添加或更新任务
     */
    public function saveTask($schedule)
    {
        $this->scheduleLibrary->saveTask($schedule);
    }
    
    /**
     * 删除任务
     */
    public function deleteTask(int $id)
    {
        
        $this->scheduleLibrary->updataTask($id);
    }
    
    /**
     * 启用/禁用任务
     */
    public function toggleTaskStatus($id, $isActive)
    {
        if($isActive == 'true'){
            try {
                // 首先检查表是否存在
                if (!Schema::hasTable('schedule_tasks')) {
                    throw new BusinessException('schedule_tasks 表不存在，请先创建表');
                }
                $task = ScheduleTask::where('is_active', false)
                ->where('id', $id)
                ->first();
                // 如果没有任务，记录日志并返回
                if (!$task) {
                    throw new BusinessException('任务不存在');
                }

                // 获取 Laravel 调度器实例
                $schedule = app(Schedule::class);
                $this->registerTask($schedule, $task);
                
                Log::info("任务 {$task->name} (ID: {$id}) 已成功注册到调度器");
            } catch (\Exception $e) {
                Log::error("注册任务失败: " . $e->getMessage());
            }
        }else{
            Log::info('我要禁用任务');
        }
       return $this->scheduleLibrary->toggleTaskStatus($id, $isActive);
    }


    public function getTaskList($credentials)
    {
        return $this->scheduleLibrary->getTaskList($credentials);
    }
} 